import base64
from django.http import JsonResponse
from rest_framework import status
import json, jwt, re, logging
from django.conf import settings
from django_redis import get_redis_connection

from users.models import User, Auth, Level, CustomerUser, CustomerUserVice
from vouchers.models import AliAuthUser
from merchants.models import MerchantUser, Merchant
from equity_mall.utils.utils import get_postallive_MD5_sign
from orders.models import APIWhiteTable

ysh_merchant_logger = logging.getLogger('ysh_merchant')
logger = logging.getLogger('django')


class UserAuthMiddle(object):
    '''登录中间件'''

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        path = request.path
        if 'sms_codes' in path or '/customer/goods/' in path or '/customer/merchant/' in path:
            path = re.sub(r'\d+/$', '', path)
        if path not in ['/admin/login/', '/admin/sms_codes/', '/voucher/login/', '/manager/login/', '/manager/sms_codes/', '/customer/login/',
                        '/customer/allow_couponinfo/', '/customer/goods/', '/customer/coupon/', '/customer/industry/',
                        '/admin/export_loanuserinfo/', '/customer/generatescheme/', '/customer/launchedgoods/', '/customer/level/', '/customer/activity_city/',
                        '/customer/merchant/', '/customer/navigation_bar/', '/promotion/transfers/', '/customer/allow_point/', '/admin/hand_movement/',
                        '/customer/allow_merchant/', '/manager/invite_manager/', '/manager/authorization_mobile/', '/manager/manager_info/', '/promotion/export_merchant_auth/',
                        '/admin/aaaa/', '/customer/applet/', '/customer/allow_cash/', '/management/login/', '/management/sms_codes/', '/admin/wxpay_cookie/', '/admin/ruiyinxin/',
                        '/voucher/payout/', '/voucher/coupons/', '/voucher/query/', '/business/login/', '/voucher/inquire/', '/voucher/distribuye/', '/voucher/activity/',
                        '/business/business_district/', '/business/alipay_district/', '/postallive/merchant/', '/voucher/ysh_distribuye/', '/voucher/ysh_merchant/',
                        '/merchantspc/login/', '/merchantspc/sms_codes/', '/voucher/haizhui/', '/admin/merchant_data/', '/voucher/meituan_result/',
                        '/customer/allow_couponbag/', '/voucher/haizhui_distribuye/', '/voucher/haizhui_inquire/', '/voucher/ylx_activity/',
                        '/voucher/ylx_inquire/', '/voucher/ylx_distribuye/', '/business/get_ylx_jump_parameter/',
                        '/merchant/auth_big_turntable/', '/merchant/auth_lucky_draw/', '/merchant/auth_lucky_draw_list/', '/merchant/receive_auth_lucky_draw/']:
            if '/admin/' in path:
                try:
                    JWT_TOKEN = request.META.get('HTTP_AUTHORIZATION')[request.META.get('HTTP_AUTHORIZATION').find(' ')+1:]
                    request.META['HTTP_AUTHORIZATION'] = JWT_TOKEN
                    payload = jwt.decode(JWT_TOKEN, settings.SECRET_KEY, issuer='xinxiang', algorithms=['HS256'])
                except jwt.DecodeError:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '账号在其他设备登录，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except jwt.ExpiredSignatureError:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '签名过期，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except jwt.InvalidTokenError:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '令牌无效，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except Exception:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '其它错误，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                if not payload:
                    return JsonResponse({'error': '请登录'}, status=status.HTTP_400_BAD_REQUEST)
                iser = User.objects.get(pk=payload['data']['id'])
                if iser.is_active != 1:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '令牌无效，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                request.iser = iser
            elif '/management/' in path:
                try:
                    JWT_TOKEN = request.META.get('HTTP_AUTHORIZATION')[request.META.get('HTTP_AUTHORIZATION').find(' ')+1:]
                    request.META['HTTP_AUTHORIZATION'] = JWT_TOKEN
                    payload = jwt.decode(JWT_TOKEN, settings.MANAGER_SECRET_KEY, issuer='manager', algorithms=['HS256'])
                except jwt.DecodeError:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '账号在其他设备登录，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except jwt.ExpiredSignatureError:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '签名过期，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except jwt.InvalidTokenError:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '令牌无效，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except Exception:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '其它错误，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                if not payload:
                    return JsonResponse({'error': '请登录'}, status=status.HTTP_400_BAD_REQUEST)
                iser = User.objects.get(pk=payload['data']['id'])
                if iser.is_active != 1:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '令牌无效，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                request.iser = iser
            elif '/voucher/' in path:
                try:
                    JWT_TOKEN = request.META.get('HTTP_AUTHORIZATION')[request.META.get('HTTP_AUTHORIZATION').find(' ')+1:]
                    request.META['HTTP_AUTHORIZATION'] = JWT_TOKEN
                    payload = jwt.decode(JWT_TOKEN, settings.SECRET_KEY1, issuer='xinheng', algorithms=['HS256'])
                except jwt.DecodeError:  # 可以在pyjwt源码中看有哪些错误
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '账号在其他设备登录，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except jwt.ExpiredSignatureError:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '签名过期，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except jwt.InvalidTokenError:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '令牌无效，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except Exception:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '其它错误，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                if not payload:
                    return JsonResponse({'error': '请登录'}, status=status.HTTP_400_BAD_REQUEST)
                request.iser = AliAuthUser.objects.get(pk=payload['data']['id'])
            elif '/manager/' in path:
                try:
                    JWT_TOKEN = request.META.get('HTTP_AUTHORIZATION')[request.META.get('HTTP_AUTHORIZATION').find(' ')+1:]
                    request.META['HTTP_AUTHORIZATION'] = JWT_TOKEN
                    payload = jwt.decode(JWT_TOKEN, settings.MANAGER_SECRET_KEY, issuer='manager', algorithms=['HS256'])
                except jwt.DecodeError:  # 可以在pyjwt源码中看有哪些错误
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '账号在其他设备登录，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except jwt.ExpiredSignatureError:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '签名过期，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except jwt.InvalidTokenError:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '令牌无效，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except Exception:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '其它错误，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                if not payload:
                    return JsonResponse({'error': '请登录'}, status=status.HTTP_400_BAD_REQUEST)
                iser = User.objects.get(pk=payload['data']['id'])
                if iser.is_active != 1:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '令牌无效，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                request.iser = iser
            elif '/customer/' in path:
                if path in ['/customer/alidiscountcoupon/', '/customer/limit_alidiscountcoupon/', '/customer/allow_coupon/', '/customer/allow_merchant_map/',
                            '/customer/allow_coupon_wyh/']:
                    try:
                        JWT_TOKEN = request.META.get('HTTP_AUTHORIZATION')[request.META.get('HTTP_AUTHORIZATION').find(' ') + 1:]
                        request.META['HTTP_AUTHORIZATION'] = JWT_TOKEN
                        payload = jwt.decode(JWT_TOKEN, settings.CUSTOMER_SECRET_KEY, issuer='customer', algorithms=['HS256'])
                        iser = CustomerUser.objects.get(pk=payload['data']['id'])
                        request.iser = iser
                        if 'is_new' in payload['data']:
                            request.is_new = payload['data']['is_new']
                        else:
                            request.is_new = ''
                    except Exception:
                        request.iser = None
                else:
                    try:
                        JWT_TOKEN = request.META.get('HTTP_AUTHORIZATION')[request.META.get('HTTP_AUTHORIZATION').find(' ')+1:]
                        request.META['HTTP_AUTHORIZATION'] = JWT_TOKEN
                        payload = jwt.decode(JWT_TOKEN, settings.CUSTOMER_SECRET_KEY, issuer='customer', algorithms=['HS256'])
                    except jwt.DecodeError:  # 可以在pyjwt源码中看有哪些错误
                        return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '账号在其他设备登录，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                    except jwt.ExpiredSignatureError:
                        return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '签名过期，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                    except jwt.InvalidTokenError:
                        return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '令牌无效，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                    except Exception:
                        return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '其它错误，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                    if not payload:
                        return JsonResponse({'error': '请登录'}, status=status.HTTP_400_BAD_REQUEST)
                    iser = CustomerUser.objects.get(pk=payload['data']['id'])
                    request.iser = iser
                    if 'is_new' in payload['data']:
                        request.is_new = payload['data']['is_new']
                    else:
                        request.is_new = ''
            elif '/cpay/' in path:
                pass
            elif '/wxapi/' in path:
                pass
            elif '/postallive/' in path:
                x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
                Sign_App_Timestamp = request.META.get('HTTP_SIGN_APP_TIMESTAMP')
                Sign_App_Nonce = request.META.get('HTTP_SIGN_APP_NONCE')
                Sign_App_Id = request.META.get('HTTP_SIGN_APP_ID')
                Sign_App_Signture = request.META.get('HTTP_SIGN_APP_SIGNTURE')
                data = request.POST.get('data', None)
                method = request.POST.get('method', None)
                if x_forwarded_for:
                    ip = x_forwarded_for.split(',')[0]
                else:
                    ip = request.META.get('REMOTE_ADDR')
                ysh_merchant_logger.info(f'{ip}&method={method}&data={data}')
                print(ip)
                ip_white_table = APIWhiteTable.objects.filter(char=ip, user_id=1)
                if not ip_white_table:
                    return JsonResponse({'retCode': '其他', 'retMessage': '非白名单内ip,请联系管理员处理'}, status=status.HTTP_200_OK)
                # if not all([Sign_App_Id, Sign_App_Nonce, Sign_App_Signture, Sign_App_Timestamp]):
                #     return JsonResponse({'retCode': '其他', 'retMessage': '请求头参数格式有误'}, status=status.HTTP_200_OK)
                # secretKey = 'waqSG35dmxVepznYnyM4rXjLnE8wBxi7'
                # data_dict = {
                #     "data": data,
                #     "method": method,
                #     "timestamp": Sign_App_Timestamp,
                #     "nonce": Sign_App_Nonce,
                #     "appId": Sign_App_Id,
                # }
                # Signture = get_postallive_MD5_sign(data_dict, secretKey)
                # if Signture != Sign_App_Signture:
                #     return JsonResponse({'retCode': '其他', 'retMessage': '验签不通过'}, status=status.HTTP_200_OK)
            elif '/business/' in path:
                try:
                    JWT_TOKEN = request.META.get('HTTP_AUTHORIZATION')[request.META.get('HTTP_AUTHORIZATION').find(' ')+1:]
                    request.META['HTTP_AUTHORIZATION'] = JWT_TOKEN
                    payload = jwt.decode(JWT_TOKEN, settings.CUSTOMER_SECRET_KEY, issuer='business', algorithms=['HS256'])
                except jwt.DecodeError:  # 可以在pyjwt源码中看有哪些错误
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '账号在其他设备登录，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except jwt.ExpiredSignatureError:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '签名过期，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except jwt.InvalidTokenError:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '令牌无效，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except Exception:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '其它错误，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                if not payload:
                    return JsonResponse({'error': '请登录'}, status=status.HTTP_400_BAD_REQUEST)
                iser = CustomerUserVice.objects.get(pk=payload['data']['id'])
                # if iser.id == 2707851:
                #     return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '账号在其他设备登录，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                request.iser = iser
            elif '/merchant/' in path:
                try:
                    JWT_TOKEN = request.META.get('HTTP_AUTHORIZATION')[request.META.get('HTTP_AUTHORIZATION').find(' ')+1:]
                    request.META['HTTP_AUTHORIZATION'] = JWT_TOKEN
                    payload = jwt.decode(JWT_TOKEN, settings.MERCHANT_SECRET_KEY, issuer='wuzhiming', algorithms=['HS256'])
                except jwt.DecodeError:  # 可以在pyjwt源码中看有哪些错误
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '账号在其他设备登录，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except jwt.ExpiredSignatureError:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '签名过期，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except jwt.InvalidTokenError:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '令牌无效，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except Exception:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '其它错误，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                if not payload:
                    return JsonResponse({'error': '请登录'}, status=status.HTTP_400_BAD_REQUEST)
                iser = MerchantUser.objects.filter(mobile=payload['data']['mobile_phone']).first()
                if not iser:
                    iser, create = MerchantUser.objects.update_or_create(
                        defaults={
                            'openid': payload['data']['openid'],
                            'mobile': payload['data']['mobile_phone']
                        }, mobile=payload['data']['mobile_phone']
                    )
                    if create:
                        try:
                            Merchant.objects.filter(managermobile=payload['data']['mobile_phone']).update(merchant_user_id=iser.id)
                        except:
                            pass
                else:
                    if not iser.openid or iser.openid != payload['data']['openid']:
                        iser.openid = payload['data']['openid']
                        iser.save()
                request.iser = iser
            elif '/merchantspc/' in path:
                try:
                    JWT_TOKEN = request.META.get('HTTP_AUTHORIZATION')[request.META.get('HTTP_AUTHORIZATION').find(' ')+1:]
                    request.META['HTTP_AUTHORIZATION'] = JWT_TOKEN
                    payload = jwt.decode(JWT_TOKEN, settings.MERCHANT_SECRET_KEY, issuer='merchantspc', algorithms=['HS256'])
                except jwt.DecodeError:  # 可以在pyjwt源码中看有哪些错误
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '账号在其他设备登录，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except jwt.ExpiredSignatureError:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '签名过期，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except jwt.InvalidTokenError:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '令牌无效，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                except Exception:
                    return JsonResponse({'state_value': 0, 'status_code': 401, 'msg': '其它错误，请退出后重新登陆'}, status=status.HTTP_401_UNAUTHORIZED)
                if not payload:
                    return JsonResponse({'error': '请登录'}, status=status.HTTP_400_BAD_REQUEST)
                iser = MerchantUser.objects.filter(id=payload['data']['id']).first()
                if not iser:
                    iser, create = MerchantUser.objects.update_or_create(defaults={'mobile': payload['data']['mobile_phone']}, mobile=payload['data']['mobile_phone'])
                    if create:
                        try:
                            Merchant.objects.filter(managermobile=payload['data']['mobile_phone']).update(merchant_user_id=iser.id)
                        except:
                            pass
                request.iser = iser
                if payload['data']['merchant_id']:
                    merchant = Merchant.objects.filter(id=payload['data']['merchant_id']).first()
                    request.merchant = merchant
                else:
                    if path in ['/merchantspc/info/', '/merchantspc/choices_merchant/']:
                        request.merchant = None
                    else:
                        return JsonResponse({'state_value': 0, 'status_code': 402, 'msg': '请选择对应商户'}, status=status.HTTP_402_PAYMENT_REQUIRED)
        redis_conn = get_redis_connection("restrict_interview")
        restrict_interview_list = ['/business/lucky_draw/', '/merchant/lucky_draw/', '/customer/turnplate/', '/business/everyday_sign_in/', '/admin/add_stock_mchid/', '/business/bank_receive_cash/']
        if path in restrict_interview_list:
            if '/management/' in path:
                visit_flag = redis_conn.get("management_visit_flag_%s" % iser.id)
            elif '/admin/' in path:
                visit_flag = redis_conn.get("admin_visit_flag_%s" % iser.id)
            elif '/customer/' in path:
                visit_flag = redis_conn.get("customer_visit_flag_%s" % iser.id)
            elif '/business/' in path:
                visit_flag = redis_conn.get("business_visit_flag_%s" % iser.id)
            elif '/merchant/' in path:
                visit_flag = redis_conn.get("merchant_visit_flag_%s" % iser.id)
            else:
                visit_flag = None
            if visit_flag:
                return JsonResponse({'error': '请求过于频繁,请稍后再试'}, status=status.HTTP_400_BAD_REQUEST)
            if '/management/' in path:
                redis_conn.set("management_visit_flag_%s" % iser.id, 1)
            elif '/admin/' in path:
                redis_conn.set("admin_visit_flag_%s" % iser.id, 1)
            elif '/customer/' in path:
                redis_conn.set("customer_visit_flag_%s" % iser.id, 1)
            elif '/business/' in path:
                redis_conn.set("business_visit_flag_%s" % iser.id, 1)
            elif '/merchant/' in path:
                redis_conn.set("merchant_visit_flag_%s" % iser.id, 1)
        response = self.get_response(request)
        if path in restrict_interview_list:
            if '/management/' in path:
                redis_conn.delete("management_visit_flag_%s" % iser.id)
            elif '/admin/' in path:
                redis_conn.delete("admin_visit_flag_%s" % iser.id)
            elif '/customer/' in path:
                redis_conn.delete("customer_visit_flag_%s" % iser.id)
            elif '/business/' in path:
                redis_conn.delete("business_visit_flag_%s" % iser.id)
            elif '/merchant/' in path:
                redis_conn.delete("merchant_visit_flag_%s" % iser.id)
        if response.status_code == 500:
            if path == "/postallive/merchant/":
                return JsonResponse({'data': [], 'retMessage': '系统繁忙,请稍后再试', 'retCode': -1}, status=status.HTTP_200_OK)
            return JsonResponse({'error': '系统繁忙,请稍后再试'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        if response.status_code == 405:
            return JsonResponse({'error': '方法不被允许。'}, status=status.HTTP_405_METHOD_NOT_ALLOWED)
        return response

